package cn.sjx.graduate.service.impl;

import cn.sjx.graduate.domain.Department;
import cn.sjx.graduate.domain.Employee;
import cn.sjx.graduate.domain.Staff;
import cn.sjx.graduate.dto.EmployeeDTO;
import cn.sjx.graduate.exception.BusinessException;
import cn.sjx.graduate.mapper.EmployeeMapper;
import cn.sjx.graduate.qo.QueryObject;
import cn.sjx.graduate.service.IDepartmentService;
import cn.sjx.graduate.service.IEmployeeService;
import cn.sjx.graduate.service.IRedisService;
import cn.sjx.graduate.service.IStaffService;
import cn.sjx.graduate.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.Expression;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author bo-feifei
 * @since 2021-11-07
 */
@Service
@Slf4j
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements IEmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private IStaffService staffService;

    @Override
    public PageInfo<Employee> query(QueryObject qo) {
        PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
        List<Employee> employees = employeeMapper.findAll(qo);
        return new PageInfo<>(employees);
    }

    @Override
    public Employee getEmployeeByUsername(String username) {
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        return super.getOne(wrapper);
    }

    @Override
    public Map<String, Object> login(Employee employee) {
        String username = employee.getUsername();
        String password = employee.getPassword();
        AssertUtil.hasText(username,"账号不能为空");
        AssertUtil.hasText(password,"密码不能为空");

        Md5Hash hashPassword = new Md5Hash(password,username,3);

        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        wrapper.eq("password",hashPassword.toString());
        Employee user = getOne(wrapper);

        if (user == null) {
            throw new BusinessException("账号密码输入错误，请重新输入");
        }
        if (user.getDeleted() == 1) {
            throw new BusinessException("该用户已经删除");
        }

        String token = UUID.randomUUID().toString().replace("-", "");
        String userStr = JSON.toJSONString(user);
        // 将用户信息保存到缓存中
        redisService.setUserByToken(token,userStr);
        // 返回响应数据，让前端保存token
        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        map.put("user",user);

        return map;
    }

    @Override
    public IPage<Employee> queryPage(QueryObject qo) {
        IPage<Employee> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        QueryWrapper<Employee> query = Wrappers.query();
        if (StringUtils.isNotBlank(qo.getKeyword())) {
            query.eq("nickname",qo.getKeyword());
        }
        query.eq("deleted",0);
        IPage<Employee> page1 = super.page(page, query);
        List<Employee> records = page1.getRecords();
        for (int i = 0; i < records.size(); i++) {
            Employee employee = records.get(i);
            Integer dept = employee.getDept();
            Department byId = departmentService.getById(dept);
            employee.setDeptName(byId.getName());
        }
        page1.setTotal(records.size());
        return page1;
    }

    @Override
    public void saveEmployee(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();
        // 获取相应的教职工等级
        Integer type = employeeDTO.getType();
        BeanUtils.copyProperties(employeeDTO,employee);
        if (employeeDTO.getAdmin() == 1) {
            employee.setAdmin(true);
        } else {
            employee.setAdmin(false);
        }
        // 对密码进行加密
        String password = employee.getPassword();
        Md5Hash hashPassword = new Md5Hash(password,employee.getUsername(),3);
        employee.setPassword(hashPassword.toString());
        this.save(employee);
        // 新增过后 有相应的employeeId
        Long employeeId = employee.getId();
        Staff staff = new Staff();
        staff.setEmployeeId(employeeId);
        staff.setName(employee.getNickname());
        staff.setBasicWorkload("156");
        staff.setType(type);
        staff.setPayoffTime(new Date());
        staff.setCreateTime(new Date());
        staffService.save(staff);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEmployee(EmployeeDTO employeeDTO) {
        Long id = employeeDTO.getId();
        Employee employee = getById(id);
        String oldPassword = employeeDTO.getOldPassword();
        if (StringUtils.isNotBlank(oldPassword)) {
            Md5Hash hashOldPwd = new Md5Hash(oldPassword,employee.getUsername(),3);
            if (!hashOldPwd.toString().equals(employee.getPassword())) {
                log.error("修改密码错误，老密码输入错误");
                throw new BusinessException("老密码输入错误");
            }
        }
        BeanUtils.copyProperties(employeeDTO,employee);
        if (employeeDTO.getAdmin() == 1) {
            employee.setAdmin(true);
        } else {
            employee.setAdmin(false);
        }
        String password = employeeDTO.getPassword();
        //这个获取到的是数据库加密之后的，再加密就会出错了
        //这个地方现在是管理员编辑用户信息，，管理员没有修改密码的权力
//        Md5Hash hashPassword = new Md5Hash(password,employee.getUsername(),3);
//        employee.setPassword(hashPassword.toString());
        employee.setPassword(password);
        this.saveOrUpdate(employee);

        if (employeeDTO.getType() != null) {
            QueryWrapper<Staff> wrapper = new QueryWrapper<>();
            wrapper.eq("employee_id", id);
            Staff staff = staffService.getOne(wrapper);
            staff.setName(employee.getNickname());
            staff.setType(employeeDTO.getType());
            staffService.saveOrUpdate(staff);
        }


    }
}
